package com.sunrise.xdoc.helper;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.GenericJDBCException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.transaction.TransactionSystemException;

/**
 * Class used to find the property name of the message of a sql error.
 * 
 * @author pmd
 */
final public class SqlErrorMessageTranslator {

	private SqlErrorMessageTranslator() {
	}

	/**
	 * Returns the property name used to translate a sql error; null if the
	 * exception is doesn't contains a translatable sql error.
	 * 
	 * @param e
	 *            exception to translate
	 * @param entityClass
	 *            entity class used to construct the property name; can be null
	 * @return property name of the message or null
	 */
	public static String getSqlErrorTranslatedMessage(Exception e, Class<?> entityClass) {
		return getSqlErrorTranslatedMessage(e, entityClass.getSimpleName(), null);
	}

	/**
	 * Returns the property name used to translate a sql error; null if the
	 * exception does not contains a translatable sql error.
	 * 
	 * @param e
	 *            exception to translate
	 * @param entityClass
	 *            String representing the entity class used to construct the
	 *            property name; can be null
	 * @param specificMessage
	 *            a specific message key to enhance the context of the searched
	 *            message; will be used so that the fallback mechanism for
	 *            messages lookup finally find the message as if this property
	 *            was not set; this property can be null
	 * @return
	 */
	public static String getSqlErrorTranslatedMessage(Exception e, String entityClass, String specificMessage) {
		String propertyName = null;

		String prefix;
		if (StringUtils.isEmpty(entityClass)) {
			prefix = Constants.MESSAGE_CODE_PREFIX
					+ (StringUtils.isEmpty(specificMessage) ? "" : specificMessage + ".");
		} else {
			prefix = Constants.MESSAGE_CODE_PREFIX
					+ (StringUtils.isEmpty(specificMessage) ? "" : specificMessage + ".") + entityClass + ".";
		}

		if (e instanceof DataIntegrityViolationException || e instanceof ConstraintViolationException
				|| e instanceof TransactionSystemException || e instanceof UncategorizedSQLException
				|| e instanceof ConstraintViolationException || e instanceof GenericJDBCException) {
			String uniqueConstraintName = OracleHelper.searchViolatedUniqueConstraint(e);
			String deleteConstraintName = OracleHelper.searchViolatedDeleteConstraint(e);
			String checkConstraintName = OracleHelper.searchViolatedCheckConstraint(e);
			if (!StringUtils.isEmpty(uniqueConstraintName)) {
				if (uniqueConstraintName.startsWith("UICD_")) {
					propertyName = prefix + uniqueConstraintName + Constants.MESSAGE_UNIQUE_CODE_ERROR;
				} else {
					propertyName = prefix + uniqueConstraintName + ".uniqueError";
				}
			} else if (!StringUtils.isEmpty(deleteConstraintName)) {
				propertyName = prefix + deleteConstraintName + ".deleteError";
			} else if (!StringUtils.isEmpty(checkConstraintName)) {
				propertyName = prefix + checkConstraintName + ".checkError";
			} else {
				propertyName = Constants.MESSAGE_CODE_PREFIX + "unknownConstraintViolation";
			}
		} else if (e instanceof DataRetrievalFailureException) {
			propertyName = prefix + "dataRetrievalFailure";
		}
		return propertyName;
	}
}
